#include "init.h"
#include "gui.h"



parameters* parameters::get_instance()
{
	static parameters inst( 0 );
	return &inst;
};



bool parameters::load_parameters( const char* file )
{
	ifstream fin;
	fin.open( file, ifstream::in );
	if ( !fin.good() )
	{
		cout << "ERROR WHILE OPENING PARAMETERS FILE" << endl;
		fin.close();
		return false;
	}
	string param_line;
	for ( ; ; )
	{
		getline( fin, param_line );
		if ( fin.fail() )
		{
			break;
		}
		if ( !parse_param_line ( param_line ) )
		{
			cout << "ERROR WHILE READING PARAMETERS FILE" << endl;
			fin.close();
			return false;
		}
	}
	fin.close();

	if ( !check_parameters() )
	{
		cout << "ERROR, SOME PARAMETERS ARE MISSING" << endl;
		return false;
	}

	if ( check_values() )
	{
		cout << "PARAMETERS LOADED SUCCESSFULLY" << endl;		
	}
	else
	{
		cout << "PARAMETERS LOADED, SOME VALUES CHANGED" << endl;	
	}

	return true;
};



bool parameters::parse_param_line( const string& pl )
{
	if ( pl[0] == '#' )
		return true;
	istringstream sstr( pl );

	string cat;
	string name;
	string subname;
	double value;

	sstr >> cat;
	if ( cat == "" )
		return true;
	sstr >> name;

	if ( cat == "AI" )
	{
		sstr >> subname;
	}
	else
	{
		subname = "";
	}

	sstr >> value;
	if ( sstr.fail() )
		return false;

	if ( cat == "GAME" )
		game_parameters[ name ] = ( unsigned int )value;
	else if ( cat == "GUI" )
		gui_parameters[ name ] = ( unsigned int )value;
	else if ( cat == "AI" )
		ai_parameters[ name ][ subname ] = value;
	else if ( cat == "NETWORK" )
		network_parameters[ name ] = ( unsigned int )value;

	cout << "LOADED PARAMETER: " << cat << " - " << name << " " << subname << endl;

	return true;
};



bool parameters::check_parameters()
{
	if ( ( game_parameters.find( "MAX_PL" ) == game_parameters.end() ) ||
		 ( game_parameters.find( "MAX_UNITS" ) == game_parameters.end() ) ||
		 ( game_parameters.find( "START_TIME" ) == game_parameters.end() ) ||
		 ( game_parameters.find( "START_MONEY" ) == game_parameters.end() ) )
		 return false;

	if ( ( gui_parameters.find( "ICON_W" ) == gui_parameters.end() ) ||
		 ( gui_parameters.find( "ICON_H" ) == gui_parameters.end() ) )
		 return false;

	if ( ( ai_parameters.find( "GENERAL" ) == ai_parameters.end() ) ||
		 ( ai_parameters.find( "SEARCH" ) == ai_parameters.end() ) ||
		 ( ai_parameters.find( "SEARCH_MT" ) == ai_parameters.end() ) ||
		 ( ai_parameters.find( "MONTE_CARLO" ) == ai_parameters.end() ) )
		return false;

	if ( ( ai_parameters[ "GENERAL" ].find( "ai_delay" ) == ai_parameters[ "GENERAL" ].end() ) || 
		 ( ai_parameters[ "GENERAL" ].find( "army_balance_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "army_vulnerability_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "army_distances_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "test_range" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "SEARCH" ].find( "depth" ) == ai_parameters[ "SEARCH" ].end() ) ||
		 ( ai_parameters[ "SEARCH_MT" ].find( "depth" ) == ai_parameters[ "SEARCH_MT" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO" ].find( "depth" ) == ai_parameters[ "MONTE_CARLO" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO" ].find( "width" ) == ai_parameters[ "MONTE_CARLO" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO" ].find( "width_plans" ) == ai_parameters[ "MONTE_CARLO" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO" ].find( "nxt_coef" ) == ai_parameters[ "MONTE_CARLO" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO" ].find( "pref_coef" ) == ai_parameters[ "MONTE_CARLO" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO" ].find( "rand_coef" ) == ai_parameters[ "MONTE_CARLO" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO_MT" ].find( "depth" ) == ai_parameters[ "MONTE_CARLO_MT" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO_MT" ].find( "width" ) == ai_parameters[ "MONTE_CARLO_MT" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO_MT" ].find( "width_plans" ) == ai_parameters[ "MONTE_CARLO_MT" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO_MT" ].find( "nxt_coef" ) == ai_parameters[ "MONTE_CARLO_MT" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO_MT" ].find( "pref_coef" ) == ai_parameters[ "MONTE_CARLO_MT" ].end() ) ||
		 ( ai_parameters[ "MONTE_CARLO_MT" ].find( "rand_coef" ) == ai_parameters[ "MONTE_CARLO_MT" ].end() ) )
		 return false;

	return true;
};



bool parameters::check_values()
{
	bool ok = true;

	if ( game_parameters[ "MAX_PL" ] < 2 )
	{
		game_parameters[ "MAX_PL" ] = 2;
		ok = false;
	}

	//maximum number of players is 9 due to architectional constraints
	if ( game_parameters[ "MAX_PL" ] > parameters::DEFINED_PLAYERS_RESOURCES )
	{
		game_parameters[ "MAX_PL" ] = parameters::DEFINED_PLAYERS_RESOURCES;
		ok = false;
	}

	if ( game_parameters[ "MAX_UNITS" ] < 1 )
	{
		game_parameters[ "MAX_UNITS" ] = 1;
		ok = false;
	}

	if ( game_parameters[ "START_TIME" ] < 1 )
	{
		game_parameters[ "START_TIME" ] = 1;
		ok = false;
	}

	//constraint due to path length overflow
	if ( game_parameters[ "START_TIME" ] > 20000 )
	{
		game_parameters[ "START_TIME" ] = 20000;
		ok = false;
	}

	if ( game_parameters[ "START_MONEY" ] < 1 )
	{
		game_parameters[ "START_MONEY" ] = 1;
		ok = false;
	}

	if ( gui_parameters[ "ICON_W" ] < 1 )
	{
		gui_parameters[ "ICON_W" ] = 1;
		ok = false;
	}

	if ( gui_parameters[ "ICON_H" ] < 1 )
	{
		gui_parameters[ "ICON_H" ] = 1;
		ok = false;
	}

	if ( ai_parameters[ "GENERAL" ][ "test_range" ] < 0 )
	{
		ai_parameters[ "GENERAL" ][ "test_range" ] = 0;
		ok = false;
	}

	if ( ai_parameters[ "GENERAL" ][ "ai_delay" ] < 2 )
	{
		ai_parameters[ "GENERAL" ][ "ai_delay" ] = 2;
		ok = false;
	}

	if ( ai_parameters[ "SEARCH" ][ "depth" ] < 1 )
	{
		ai_parameters[ "SEARCH" ][ "depth" ] = 1;
		ok = false;
	}

	if ( ai_parameters[ "SEARCH_MT" ][ "depth" ] < 1 )
	{
		ai_parameters[ "SEARCH_MT" ][ "depth" ] = 1;
		ok = false;
	}

	if ( ai_parameters[ "MONTE_CARLO" ][ "depth" ] < 1 )
	{
		ai_parameters[ "MONTE_CARLO" ][ "depth" ] = 1;
		ok = false;
	}

	if ( ai_parameters[ "MONTE_CARLO" ][ "width" ] < 1 )
	{
		ai_parameters[ "MONTE_CARLO" ][ "width" ] = 1;
		ok = false;
	}

	if ( ai_parameters[ "MONTE_CARLO" ][ "width_plans" ] < 1 )
	{
		ai_parameters[ "MONTE_CARLO" ][ "width_plans" ] = 1;
		ok = false;
	}

	if ( ai_parameters[ "MONTE_CARLO" ][ "rand_coef" ] < 0 )
	{
		ai_parameters[ "MONTE_CARLO" ][ "rand_coef" ] = 0.5;
		ok = false;
	}

	if ( ( int )ceil( ai_parameters[ "MONTE_CARLO" ][ "pref_coef" ] ) % 2 == 0 )
	{
		ai_parameters[ "MONTE_CARLO" ][ "pref_coef" ] = ceil( ai_parameters[ "MONTE_CARLO" ][ "pref_coef" ] ) + 1;
		ok = false;
	}
	else
	{
		ai_parameters[ "MONTE_CARLO" ][ "pref_coef" ] = ceil( ai_parameters[ "MONTE_CARLO" ][ "pref_coef" ] );
	}

	if ( ai_parameters[ "MONTE_CARLO_MT" ][ "depth" ] < 1 )
	{
		ai_parameters[ "MONTE_CARLO_MT" ][ "depth" ] = 1;
		ok = false;
	}

	if ( ai_parameters[ "MONTE_CARLO_MT" ][ "width" ] < 1 )
	{
		ai_parameters[ "MONTE_CARLO_MT" ][ "width" ] = 1;
		ok = false;
	}

	if ( ai_parameters[ "MONTE_CARLO_MT" ][ "width_plans" ] < 1 )
	{
		ai_parameters[ "MONTE_CARLO_MT" ][ "width_plans" ] = 1;
		ok = false;
	}

	if ( ai_parameters[ "MONTE_CARLO_MT" ][ "rand_coef" ] < 0 )
	{
		ai_parameters[ "MONTE_CARLO_MT" ][ "rand_coef" ] = 0.5;
		ok = false;
	}

	if ( ( int )ceil( ai_parameters[ "MONTE_CARLO_MT" ][ "pref_coef" ] ) % 2 == 0 )
	{
		ai_parameters[ "MONTE_CARLO_MT" ][ "pref_coef" ] = ceil( ai_parameters[ "MONTE_CARLO_MT" ][ "pref_coef" ] ) + 1;
		ok = false;
	}
	else
	{
		ai_parameters[ "MONTE_CARLO_MT" ][ "pref_coef" ] = ceil( ai_parameters[ "MONTE_CARLO_MT" ][ "pref_coef" ] );
	}

	return ok;
};